package com.workManager.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.workManager.exception.BusinessException;
import com.workManager.mapper.TbParameterMapper;
import com.workManager.mapper.TbProjectTasktimeMapper;
import com.workManager.mapper.TdAuthorityMapper;
import com.workManager.mapper.TdUserMapper;
import com.workManager.pojo.*;
import com.workManager.util.DateUtil;
import com.workManager.util.ExcelReadUtil;
import com.workManager.util.ValidateUtil;
import com.workManager.vo.CountProjectVo;
import com.workManager.vo.ProjectDetailVo;
import com.workManager.vo.ProjectVo;
import com.workManager.vo.TaskTimeTypeVo;
import org.apache.commons.lang3.math.Fraction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.util.*;

/**
 * Created by Thinkpad on 2017/1/18 0018.
 */
@Service
public class ProjectTasktimeServiceImpl implements  ProjectTasktimeService {

    @Autowired
    private TbProjectTasktimeMapper projectTasktimeMapper;

    @Autowired
    private ProjectService projectService;

    @Autowired
    private TdUserMapper userMapper;

    @Autowired
    private TbParameterMapper parameterMapper;

    @Transactional
    public void uploadExcel(String name , MultipartFile file) throws  Exception{

        List<String[]> fileData = ExcelReadUtil.excelToList(name,file.getInputStream());

        StringBuilder stringBuilder = new StringBuilder();

        String[] tableHead = fileData.get(0);
        String[] headTitle = {"年份","月份","姓名"};
        for (int i=0;i<headTitle.length;i++){
            String  headItem = tableHead[i];
            if(!headItem.equals(headTitle[i])){
                throw  new BusinessException("表格格式不正确，请参考人力分配导入模板重新上传(行：1，列："+(i+1)+")");
            }
        }

        //获取系统定义的项目列表
        List<TbProject> projectList = projectService.getAllProjects();
        //获取项目编号列表
        //List<String> projectCodeList = projectService.getProjectCodeList(projectList);

        //获取项目编号与ID键值对
        Map<String,Integer> projectCodeMap = projectService.getCodeAndIdMapByProjects(projectList);

        //检查上传文件的项目编号是否正确
        String[] projectCodes = Arrays.copyOfRange(tableHead, 3, tableHead.length);
        //List<String> list = Arrays.asList(projectCodes);
        //List<String> arrayList = new ArrayList<String>(list);
        //arrayList.removeAll(projectCodeList);
        for(String code:projectCodes){
            Map<String,Object> map = new HashMap<>();
            map.put("projectCode",code);
            ProjectVo vo = projectService.queryByCodeName(map);
            if(null == vo){
                stringBuilder.append("系统未定义项目编号：" + code)
                        .append(System.getProperty("line.separator"));
            }else if(vo.getProjectStatusName()!=null&&vo.getProjectStatusName().equals("已完结")){
                stringBuilder.append("项目编号：" + code + " 已完结！")
                        .append(System.getProperty("line.separator"));
            }else if(vo.getProjectStatusName()!=null&&vo.getProjectStatusName().equals("已终结")){
                stringBuilder.append("项目编号：" + code + " 已终结！")
                        .append(System.getProperty("line.separator"));
            }
        }
//        if(arrayList.size() > 0){
//            //throw  new BusinessException("上传失败，系统未定义项目编号：" + Arrays.toString(arrayList.toArray()));
//            stringBuilder.append("系统未定义项目编号：" + Arrays.toString(arrayList.toArray()))
//                    .append(System.getProperty("line.separator"));
//        }

        List<TbProjectTasktime> newProjectTaskTimeList = new ArrayList<TbProjectTasktime>();
//        List<TbProjectTasktime> oldProjectTaskTimeList = new ArrayList<TbProjectTasktime>();
//        List<TbProjectTasktime> delProjectTaskTimeList = new ArrayList<TbProjectTasktime>();
        Date createDate = new Date();

        TbParameter parameter= parameterMapper.getParamByTypeAndName("人天类型", "其他");
        if(parameter == null){
            throw  new BusinessException("上传失败，请联系系统管理员添加\"人天类型\"的参数：\"其他\"");
        }
        Integer taskTimeType = parameter.getParamId();

        Map<String, Object> conditionMap = new HashMap<String, Object>();
        String[] firstData = fileData.get(1);
        //设置费用发生为指定月份的最后一天
        int costYear = Integer.parseInt(firstData[0]);
        int costMonth = Integer.parseInt(firstData[1]);
        Date firstDay = DateUtil.getFirstDayOfMonth(costYear, costMonth);
        Date lastDay = DateUtil.getLastDayOfMonth(costYear, costMonth);
        conditionMap.put("startTime", firstDay);
        conditionMap.put("endTime", lastDay);


        //读取人天数据
        for(int i=1;i<fileData.size();i++){
            String[] rowData = fileData.get(i);

            //检查是否空行
            if(ExcelReadUtil.isBlankRow(rowData)){
                continue;
            }

            String userName = rowData[2];
            TdUser user = userMapper.queryUserByName(userName);
            if(user==null) {
                stringBuilder.append("姓名：" + userName + " 不存在(行："+(i+1)+"，列：3)")
                        .append("\r\n");
            }

            for(int j=3; j<rowData.length; j++){
                TbProjectTasktime projectTasktime = new TbProjectTasktime();
                projectTasktime.setProjectId(projectCodeMap.get(tableHead[j]));
                projectTasktime.setUserId(user == null ? null : user.getUserId());

                String taskTime = rowData[j];


                if(taskTime ==null || taskTime.trim().length() == 0 || "0".equals(taskTime.trim())){    //校验空或0值的数据
                    taskTime = "0";
                    projectTasktime.setTasktime(new BigDecimal(taskTime));
                }else if(taskTime.indexOf("/") > 0){    //校验分数
                    String[] temp = taskTime.split("/");
                    if(temp.length ==2 && ValidateUtil.Z_index(temp[0]) && ValidateUtil.Z_index(temp[1]) ){
                        Fraction fraction = Fraction.getFraction(Integer.parseInt(temp[0]), Integer.parseInt(temp[1]));
                        projectTasktime.setTasktime(new BigDecimal(fraction.doubleValue()));
                    }else{
                        stringBuilder.append("项目人天格式不正确(行："+(i+1)+"，列："+(j+1)+")")
                                .append("\r\n");
                    }
                }else if (ValidateUtil.Z_index(taskTime) ){    //校验正整数
                    int tempTaskTime = Integer.parseInt(taskTime);
                    if(tempTaskTime>=30){
                        stringBuilder.append("项目人天不能大于30(行："+(i+1)+"，列："+(j+1)+")")
                                .append("\r\n");
                    }
                    projectTasktime.setTasktime(new BigDecimal(taskTime));
                }else if(ValidateUtil.Posttive_float(taskTime)){    //校验浮点数
                    float tempTaskTime = Float.parseFloat(taskTime);
                    if(tempTaskTime > 30){
                        stringBuilder.append("项目人天不能大于30(行："+(i+1)+"，列："+(j+1)+")")
                                .append("\n");
                    }
                    projectTasktime.setTasktime(new BigDecimal(taskTime));
                }else{
                    stringBuilder.append("项目人天格式不正确(行："+(i+1)+"，列："+(j+1)+")")
                            .append("\r\n");
                }

                projectTasktime.setTasktimeDate(lastDay);
                projectTasktime.setTasktimeType(taskTimeType);
                projectTasktime.setCreateDate(createDate);
                projectTasktime.setIsValid(true);

                if(!"0".equals(taskTime)){
                    newProjectTaskTimeList.add(projectTasktime);
                }

            }

        }

        if(stringBuilder.length() > 0){
            throw  new BusinessException(stringBuilder.toString());
        }

        //删除旧数据
        projectTasktimeMapper.deleteByConditions(conditionMap);

        //插入新数据
        if(newProjectTaskTimeList.size() > 0 ){
            projectTasktimeMapper.batchInsert(newProjectTaskTimeList);
        }


    }

    public PageInfo<TbProjectTasktime> queryforPage(Map<String,Object> map) {
        int pageno = !map.containsKey("pagenum")||map.get("pagenum")==null?1:Integer.parseInt(map.get("pagenum").toString());
        int pagesize = !map.containsKey("pagesize")||map.get("pagesize")==null?10:Integer.parseInt(map.get("pagesize").toString());
        PageHelper.startPage(pageno,pagesize);
        List<TbProjectTasktime> projectTasktimeList = projectTasktimeMapper.queryforPage(map);
        PageInfo<TbProjectTasktime> pageInfo = new PageInfo<TbProjectTasktime>(projectTasktimeList);
        return pageInfo;

    }

   public PageInfo<CountProjectVo> countByProject(Map<String, Object> map) {
       int pageno = !map.containsKey("pagenum")||map.get("pagenum")==null?1:Integer.parseInt(map.get("pagenum").toString());
       int pagesize = !map.containsKey("pagesize")||map.get("pagesize")==null?10:Integer.parseInt(map.get("pagesize").toString());
        PageHelper.startPage(pageno,pagesize);
        List<CountProjectVo> projectVos = projectTasktimeMapper.countByProject(map);
       PageInfo<CountProjectVo> pageInfo = new PageInfo<CountProjectVo>(projectVos);
       return  pageInfo;
    }

    public PageInfo<ProjectDetailVo> queryProjectDetails(Map<String, Object> map) {
        int pageno = !map.containsKey("pagenum")||map.get("pagenum")==null?1:Integer.parseInt(map.get("pagenum").toString());
        int pagesize = !map.containsKey("pagesize")||map.get("pagesize")==null?10:Integer.parseInt(map.get("pagesize").toString());
        PageHelper.startPage(pageno,pagesize);
        List<ProjectDetailVo> projectDetailVoList = projectTasktimeMapper.queryProjectDetails(map);
        PageInfo<ProjectDetailVo> pageInfo = new PageInfo<ProjectDetailVo>(projectDetailVoList);
        return pageInfo;
    }

    public PageInfo<CountProjectVo> countByStaff(Map<String, Object> map) {
        int pageno = !map.containsKey("pagenum")||map.get("pagenum")==null?1:Integer.parseInt(map.get("pagenum").toString());
        int pagesize = !map.containsKey("pagesize")||map.get("pagesize")==null?10:Integer.parseInt(map.get("pagesize").toString());
        PageHelper.startPage(pageno,pagesize);
        List<CountProjectVo> projectVos = projectTasktimeMapper.countByStaff(map);
        PageInfo<CountProjectVo> pageInfo = new PageInfo<CountProjectVo>(projectVos);

        return pageInfo;
    }

    public PageInfo<CountProjectVo> countByStaffAll(Map<String, Object> map) {
        int pageno = !map.containsKey("pagenum")||map.get("pagenum")==null?1:Integer.parseInt(map.get("pagenum").toString());
        int pagesize = !map.containsKey("pagesize")||map.get("pagesize")==null?10:Integer.parseInt(map.get("pagesize").toString());
        PageHelper.startPage(pageno,pagesize);
        List<CountProjectVo> projectVos = projectTasktimeMapper.countByStaffAll(map);
        PageInfo<CountProjectVo> pageInfo = new PageInfo<CountProjectVo>(projectVos);

        return pageInfo;
    }

    public Integer deleteByProjectIds(String[] projectIds) {
        return projectTasktimeMapper.deleteByProjectIds(projectIds);
    }

    public List<TbProjectTasktime> taskTimeChange(Map<String, Object> map) {
        return projectTasktimeMapper.taskTimeChange(map);
    }

    public List<TaskTimeTypeVo> taskTimeTypeChange(Map<String, Object> map) {

        return projectTasktimeMapper.taskTimeTypeChange(map);
    }

    public List<TaskTimeTypeVo> taskTimeStaffSpread(Map<String, Object> map) {
        return projectTasktimeMapper.taskTimeStaffSpread(map);
    }

    public List<TbProjectTasktime> taskTimeStaffChange(Map<String, Object> map) {
        return projectTasktimeMapper.taskTimeStaffChange(map);
    }

    public List<TaskTimeTypeVo> taskTimeTypeSpread2(Map<String, Object> map) {
        return projectTasktimeMapper.taskTimeTypeSpread2(map);
    }

    public List<TaskTimeTypeVo> taskTimeProjectSpread(Map<String, Object> map) {
        return projectTasktimeMapper.taskTimeProjectSpread(map);
    }

    /**
     * 检查人天数据是否已存在
     * @param projectTasktime
     * @return
     */
    public boolean isExistsProjectTasktime(TbProjectTasktime projectTasktime){
        TbProjectTasktimeExample projectTasktimeExample = new TbProjectTasktimeExample();

        projectTasktimeExample.or().andIsValidEqualTo(true)
                .andTasktimeDateEqualTo(projectTasktime.getTasktimeDate())
                .andProjectIdEqualTo(projectTasktime.getProjectId())
                .andUserIdEqualTo(projectTasktime.getUserId())
                .andTasktimeTypeEqualTo(projectTasktime.getTasktimeType());

        List<TbProjectTasktime> directExpensesList = projectTasktimeMapper.selectByExample(projectTasktimeExample);
        return directExpensesList.size() > 0 ? true : false;
    }

}
